<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
use think\facade\Session;
use think\Request;

class Index extends Controller {
	
	private $chemicalData = null;

    public function _initialize()
    {
        $request = Request::instance();
        $module = strtolower($request->module());
        $controller = strtolower($request->controller());
        $action = strtolower($request->action());
        if ($module=='index' && $controller=='index'){
            switch ($action){
                case 'index':
                case 'login':
                case 'logout':
                case 'checklogin':
                    break;
                default:
                    $type = $request->isAjax() ? 'json' : 'no-json';
                    $this->checkLogin($type);
            }
        }
    }

    public function index(){
        session_start();
        $login_status = Session::has('logining');
        $logining = 0;
        if($login_status){
            $logining = 1;
            $this->assign('username', Session::get('username'));
        }

        $this->assign('logining', $logining);
		return $this->fetch();
	}
	
    public function index_simple(){
        header("Content-type: text/html; charset=utf-8");
        echo '功能修订中....';
        exit;
		if(is_null($this->chemicalData)) $this->chemicalData = init_data();

		$this->assign('cterms', array_values($this->chemicalData['ctermData']));
		$this->assign('nterms', array_values($this->chemicalData['ntermData']));
		
		$amino = input('amino');
		$cterm = input('CTerm');
		$nterm = input('NTerm');
		
		// $cal=1 获取参数值，并赋值，便于接收外部地址链接
		$cal = input('cal', 0);
		if($cal==1){
			$this->assign('amino', $amino);
			$this->assign('cterm', $cterm);
			$this->assign('nterm', $nterm);
		}
		
		$this->assign('cal', $cal);
		return $this->fetch();
    }
	
	public function index_result(){
		header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);
		header('Access-Control-Allow-Credentials:true');
		$amino = input('amino');
		$cterm = input('CTerm');
		$nterm = input('NTerm');
		
		$needCheckData = array(
		   'amino'=>$amino,
		   'cterm'=>$cterm,
		   'nterm'=>$nterm
		);
	
		if(is_null($this->chemicalData)) $this->chemicalData = init_data();
		
		$result = calculateResult($this->chemicalData, $needCheckData);

		return json($result);
	}
	
	function about(){
		return $this->fetch();
	}

    public function index_advance(){
		$cal = input('cal', 0);
		if($cal==1){
			$amino = input('amino');
			$this->assign('amino', $amino);
		}
		
		$this->assign('cal', $cal);
        $this->assign('show', input('show', 0));
		return $this->fetch('index_advance');
	}
	
    public function result_advance(){
		header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);
		header('Access-Control-Allow-Credentials:true');
		
		$amino = input('amino');
		$subject = $amino;
		
		$s2 = input('s2');
		$cyclo_type = input('cyclo-type', -1);
		$cyclo_type_a = input('cyclo-type-A', -1);
		$cyclo_type_b = input('cyclo-type-B', -1);

		$aminoSubjectLogic = model('AminoSubject', 'logic');
		$aminoSubjectLogic->init($amino);
		$aminoSubjectLogic->mCycloType = $cyclo_type;
		$aminoSubjectLogic->mCycloTypeA = $cyclo_type_a;
		$aminoSubjectLogic->mCycloTypeB = $cyclo_type_b;
		$aminoSubjectLogic->mCustomCys = $s2;
		$aminoSubjectLogic->analyze();
		

		$result = $aminoSubjectLogic->getResult();
        $result['show']  = input('show', 0);

		if(is_null($result)){
			$result = array(
			  'hasError'=>true,
			  'message'=>'系统发生异常，无法计算'
			);
		}
		return json($result);
	}
	
	/**
	 * 肽含量计算
	 */
	public function peptide_component(){
		$amino_salts = Db::table('amino_salt')->select();
		$this->assign('salts', $amino_salts);
		return $this->fetch();
	}
	
	public function result_peptide_component(){
		header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);
		header('Access-Control-Allow-Credentials:true');
		
		$mw = input('mw');
		$acid_count = input('acidCount', 0);
		$base_count = input('baseCount', 0);
		$salt_id = input('saltId', 0);
		$purity = input('purity');
		
		$peptide_component_logic = new \app\index\logic\PeptideComponent;
		$peptide_component_logic->mMw = $mw;
		$peptide_component_logic->mAcidCount = $acid_count;
		$peptide_component_logic->mBaseCount = $base_count;
		$peptide_component_logic->mPurity = $purity;
		
		$peptide_component_logic->calculate($salt_id);
		$result = $peptide_component_logic->getResult();
		if(is_null($result) || $result==false){
			$result = array(
			   'has_error'=>true,
			   'message'=>'系统错误'
			);
		}
		
		return json($result);
	}
	
	public function synthetise_difficult(){
	    $debug = input('debug', false);
        $this->assign('debug', $debug);
		return $this->fetch();
	}
	
	public function result_synthetise_difficult(){
		$amino = input('amino');
        $debug = input('debug', false);
		
		$amino_difficult_logic = new \app\index\logic\AminoDifficult;
		$amino_difficult_logic->init($amino);
		$amino_difficult_logic->analyze();
		$result = $amino_difficult_logic->getResult();
		if(!is_null($result)){
		    $debug = is_null($debug) ? false : $debug;
            if(is_string($debug)){
                $debug = strtolower($debug)=='true' ? true : false;
            }
		    $result['debug'] = $debug;
        }
		return json($result);
	}
	
	public function synthetise_difficult_about(){
		return $this->fetch();
	}

	public function peptide_screening_tools(){
        $debug = input('debug', 'false');
        $this->assign('debug', $debug);
        if ($debug=='true'){
            return $this->fetch('peptide_screening_tools_show');
        }
        return $this->fetch();
    }

    public function result_peptide_antisense(){
        $peptide_screening_logic = new \app\index\logic\PeptideScreening;
        $amino_logic = new \app\index\logic\Amino;
        $type = input('type');
        // 反义肽
        if($type==1){
            $peptide_screening_logic->initPeptideAntisense();
            $amino = input('amino');
            $result = $peptide_screening_logic->getPeptideAntisenseResult($amino, $amino_logic);
            return json($result);
        }else if($type==11){
            $dna = input('dna');
            $result = $peptide_screening_logic->getDNAResult($dna, $amino_logic);
            return json($result);
        }else if($type==2){
            $amino = input('amino');
            $location = input('location');

            $amino_base_map = $this->getAminoBaseMap();
            $result = $peptide_screening_logic->getPeptideRandomResult($amino, $location, $amino_base_map, $amino_logic);
            return json($result);
        }else if ($type==3){
            $amino = input('amino');
            $m = input('m');
            $n = input('n');

            $amino_base_map = $this->getAminoBaseMap();

            $result = $peptide_screening_logic->getPeptideOverlappingResult($amino, $m, $n, $amino_base_map, $amino_logic);
            return json($result);
        }else if($type==4){
            $amino = input('amino');
            $a = input('a1');
            $b = input('b1');
            $dest_length = input('dest_length', 6);

            $amino_base_map = $this->getAminoBaseMap();

            $result = $peptide_screening_logic->getPeptideTruncationResult($amino, $a, $b, $dest_length, $amino_base_map, $amino_logic);
            return json($result);
        }else if($type==5){
            $amino = input('amino');

            $amino_base_map = $this->getAminoBaseMap();
            $result = $peptide_screening_logic->getPeptideAlanineResult($amino, $amino_base_map, $amino_logic);
            return json($result);
        }else if($type==6){
            $amino = input('amino');
            $location = input('location');

            $amino_base_map = $this->getAminoBaseMap();
            $result = $peptide_screening_logic->getPeptideScrambledResult($amino, $location, $amino_base_map, $amino_logic);
            return json($result);
        }else if($type==7){
            $amino = input('amino');
            $location = input('location');

            $amino_base_map = $this->getAminoBaseMap();
            $result = $peptide_screening_logic->getPeptidePositionalResult($amino, $location, $amino_base_map, $amino_logic);
            return json($result);
        }else if($type==8){
            $amino = input('amino');
            $dest_length = input('dest-length');

            $amino_base_map = $this->getAminoBaseMap();
            $result = $peptide_screening_logic->getPeptideTCellResult($amino, $dest_length, $amino_base_map, $amino_logic);
            return json($result);
        }
        return [
            'has_error'=>true,
            'message'=>'未知错误'
        ];
    }

    /**
     * 纯化难度预测及方法
     */
    public function purify_difficult(){
        $debug = input('debug', false);
        $this->assign('debug', $debug);
        return $this->fetch();
    }

    public function result_purify_difficult(){
        header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Credentials:true');

        $amino = input('amino');
        $s2 = input('s2');
        $cyclo_type = input('cyclo-type', -1);
        $cyclo_type_a = input('cyclo-type-A', -1);
        $cyclo_type_b = input('cyclo-type-B', -1);

        $purify_difficult_logic = new \app\index\logic\PurifyDifficult;
        $purify_difficult_logic->init($amino);
        $purify_difficult_logic->mCycloType = $cyclo_type;
        $purify_difficult_logic->mCycloTypeA = $cyclo_type_a;
        $purify_difficult_logic->mCycloTypeB = $cyclo_type_b;
        $purify_difficult_logic->mCustomCys = $s2;
        $purify_difficult_logic->analyze();

        $result = $purify_difficult_logic->getResult();
        if(is_null($result)){
            $result = array(
                'hasError'=>true,
                'message'=>'系统发生异常，无法计算'
            );
        }
        return json($result);
    }

    /**
     * 杂质分析工具
     */
    public function peptide_impurity(){
        $debug = input('debug', false);
        $this->assign('debug', $debug);
        return $this->fetch();
    }

    public function result_peptide_impurity(){
        header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Credentials:true');

        $amino = input('amino');
        $carrier_type = input('carrier_type');
        $synthetic_method = input('synthetic_method');
        $n = input('n');
        $has_operate = input('has_operate');
        $operate_location = input('operate_location');
        $impurity_weight = input('impurity_weight');
        $custom_cys = input('s2');
        $debug = input('debug', false);

        $peptide_impurity_logic = new \app\index\logic\PeptideImpurity;
        $peptide_impurity_logic->init($amino);
        $peptide_impurity_logic->mCarrierType = $carrier_type;
        $peptide_impurity_logic->mSyntheticMethod = $synthetic_method;
        $peptide_impurity_logic->mN = $n;
        $peptide_impurity_logic->mHasOperate = $has_operate;
        $peptide_impurity_logic->mOperateLocation = $operate_location;
        $peptide_impurity_logic->mImpurityWeight = $impurity_weight;
        $peptide_impurity_logic->mCustomCys = $custom_cys;
        $peptide_impurity_logic->mDebug = $debug;

        $peptide_impurity_logic->analyze();

        $result = $peptide_impurity_logic->getResult();
        if(is_null($result)){
            $result = array(
                'hasError'=>true,
                'message'=>'系统发生异常，无法计算'
            );
        }
        return json($result);
    }

    public function dna_translate(){
        return $this->fetch();
    }

    public function result_dna_translate(){
        $dna = input('dna');
        $dna_translate_logic = new \app\index\logic\DNATranslate();
        $result = $dna_translate_logic->getDNAResult($dna);
        return json($result);
    }

    /**
     * ESI质谱同系数据对比
     */
    public function esi(){
         return $this->fetch();
    }

    public function esi_result(){
        $result = [];
        return json($result);
    }

    public function help(){
        return $this->fetch('about');
    }

    /**
     * 氨基酸标识
     * @return mixed
     */
    public function amino_detail(){
        return $this->fetch();
    }

    public function sample(){
        return $this->fetch();
    }

    /**
     * 检查登录信息
     * @param string $type josn 返回json信息，否则直接die
     */
    private function checkLogin($type="json"){
        $logining = Session::has("logining");
        if ($logining!=1){
            if ($type=="json"){
                $result = [
                    'has_error'=>true,
                    'message'=>'用户未登录，无法使用此功能'
                ];
                return json($result);
            }else{
                $this->error('用户未登录，无法使用此功能。', url('index'));
            }
        }
        return 0;
    }
    /**
     * 获取20种基础氨基酸信息，array
     * @return false|\PDOStatement|string|\think\Collection
     */
    private function getAminoBaseData(){
        return Db::name('amino_base')->select();
    }

    /**
     * 获取20种基础氨基酸信息，map，带key
     * @param string $key1 主键1
     * @param null $key2 主键2
     * @return array 基础信息map表
     */
    private function getAminoBaseMap($key1='single', $key2=null){
        $data = $this->getAminoBaseData();
        $map = array2map($data, $key1, $key2);
        return $map;
    }
	/**
	 * 是否需要计算二硫键信息
	 */
	private function needCalculateS2($s2){
		if(checkNull($s2)){
			return false;
		}
		$pattern = '/([1-9]*[0-9]+\-[1-9]*[0-9])/';
		$result = preg_match_all($pattern, $s2);
		$sList = str_split($s2, ',');
		if($result<count($sList)){
			return false;
		}
		return true;
	}
	
	/**
	 * 初始化相关的基础数据
	 */
	private function initBaseData(&$rAminoSubject, $excelFilename){
		$base_index = config('base_index');
		$result_type = config('result_type');
		$default_value = config('default_value');
		
		$rAminoSubject->mBaseIndex = $base_index;
		$rAminoSubject->mResultType = $result_type;
		$rAminoSubject->mDefaultValue = $default_value;
		
		$rAminoSubject->loadBaseData($excelFilename);
	}
}